package com.jynn.mesh.util;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.usermodel.RichTextRun;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hssf.converter.ExcelToHtmlConverter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.xwpf.converter.core.BasicURIResolver;
import org.apache.poi.xwpf.converter.core.FileImageExtractor;
import org.apache.poi.xwpf.converter.core.FileURIResolver;
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.w3c.dom.Document;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;

/**
 * 文件操作工具
 */

public class FileHandleUtils {
	/**
	 * docx文件转换成html
	 * 
	 * @param tempPath
	 *            文件存放路径
	 * @param fileName
	 *             path+fileName
	 * @param outPutFile
	 *            预览html path+fileName
	 */
	public static void docxToHtml(String tempPath, String fileName, String outPutFile)
			throws TransformerException, IOException, ParserConfigurationException {
		try {
			XWPFDocument document = new XWPFDocument(new FileInputStream(fileName));
//			XHTMLOptions options = XHTMLOptions.create().indent(4);
            //加载html页面时图片路径
            XHTMLOptions options = XHTMLOptions.create().URIResolver( new BasicURIResolver("./"));
			File imageFolder = new File(tempPath);
			options.setExtractor(new FileImageExtractor(imageFolder));
			options.URIResolver(new FileURIResolver(imageFolder));
			File outFile = new File(outPutFile);
			outFile.getParentFile().mkdirs();
			OutputStream out = new FileOutputStream(outFile);
			XHTMLConverter.getInstance().convert(document, out, options);
			out.close();
//			ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
//			XHTMLConverter.getInstance().convert(document, baos, options);  
//			String content = baos.toString();
//			System.out.println(content);
//			baos.close();
		}catch(Exception e) {
			System.out.println(e.getMessage());
		}
	}

	/**
	 * doc文件转换成html
	 */
	public static void docToHtml(String tempPath, String fileName, String outPutFile)
			throws TransformerException, IOException, ParserConfigurationException {

		HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(fileName));
		WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
				DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
		wordToHtmlConverter.setPicturesManager(new PicturesManager() {
			public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches,
					float heightInches) {
				return "img/" + suggestedName;
			}
		});
		wordToHtmlConverter.processDocument(wordDocument);
		List<Picture> pics = wordDocument.getPicturesTable().getAllPictures();
		if (pics != null) {
			for (int i = 0; i < pics.size(); i++) {
				Picture pic = (Picture) pics.get(i);
				try {
					pic.writeImageContent(new FileOutputStream(tempPath + pic.suggestFullFileName()));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
			}
		}
		Document htmlDocument = wordToHtmlConverter.getDocument();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		DOMSource domSource = new DOMSource(htmlDocument);
		StreamResult streamResult = new StreamResult(out);
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer serializer = tf.newTransformer();
		serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
		serializer.setOutputProperty(OutputKeys.INDENT, "yes");
		serializer.setOutputProperty(OutputKeys.METHOD, "html");
		serializer.transform(domSource, streamResult);
		out.close();
		writeFile(new String(out.toByteArray()), outPutFile);
	}

	/**
	 * excel .xls文件转换成html
	 */
	public static void HSSFToHtml(String tempPath, String fileName, String outPutFile)
			throws TransformerException, IOException, ParserConfigurationException {
		try {
			InputStream input = new FileInputStream(fileName);
			HSSFWorkbook excelBook = new HSSFWorkbook(input);
			ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
					DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
			excelToHtmlConverter.processWorkbook(excelBook);
			List pics = excelBook.getAllPictures();
			if (pics != null) {
				for (int i = 0; i < pics.size(); i++) {
					Picture pic = (Picture) pics.get(i);
					try {
						pic.writeImageContent(new FileOutputStream(tempPath + pic.suggestFullFileName()));
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					}
				}
			}
			Document htmlDocument = excelToHtmlConverter.getDocument();
			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
			DOMSource domSource = new DOMSource(htmlDocument);
			StreamResult streamResult = new StreamResult(outStream);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer serializer = tf.newTransformer();
			serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
			serializer.setOutputProperty(OutputKeys.INDENT, "yes");
			serializer.setOutputProperty(OutputKeys.METHOD, "html");
			serializer.transform(domSource, streamResult);
			outStream.close();
			writeFile(new String(outStream.toByteArray()), outPutFile);
		}catch(Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	public static void ppt2Image(String pptFiles, String htmlDir, String imgDir) throws Exception {
    	File pptFile = new File(pptFiles);
        FileInputStream is = new FileInputStream(pptFile);
        SlideShow ppt = new SlideShow(is);
        is.close();
        Dimension pgsize = ppt.getPageSize();
        org.apache.poi.hslf.model.Slide[] slide = ppt.getSlides();
        StringBuilder content = new StringBuilder();
        content.append("<html>");
        content.append("<body>");
        for (int i = 0; i < slide.length; i++) {
            String image = UUID.randomUUID() + ".png";
            String webImagePath = imgDir + image;
            POIUtils.createDir(imgDir);
            try {
                TextRun[] textRuns = slide[i].getTextRuns();
                for (TextRun textRun : textRuns) {
                    RichTextRun[] richTextRuns = textRun.getRichTextRuns();
                    for (RichTextRun richTextRun : richTextRuns) {
                        richTextRun.setFontIndex(1);
                        richTextRun.setFontName("宋体");
                    }
                }

                BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics = img.createGraphics();
//                graphics.setPaint(Color.white);
                graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
                slide[i].draw(graphics);

                // 这里设置图片的存放路径和图片的格式(jpeg,png,bmp等等),注意生成文件路径
                FileOutputStream out = new FileOutputStream(imgDir + image);
                ImageIO.write(img, "png", out);
                out.close();

                content.append("<br />");
                content.append("<p style=text-align:center;>");
                content.append("<img src=" + "\"").append(webImagePath).append("\"").append("/>");
                content.append("</p>");
                content.append("<br />");
            } catch (Exception e) {
                System.out.println("第" + i + "张ppt转换出错");
            }

        }

        content.append("</body>");
        content.append("</html>");
        String targetFileName = imgDir+htmlDir;
        FileUtils.writeStringToFile(new File(targetFileName), content.toString(), "utf-8");
    }

    /**
     * 检查文件是否为PPT
     */
//    private static boolean checkPPTFile(File file) {
//        String fileName = file.getName();
//        return fileName.endsWith(".ppt") || fileName.endsWith(".pptx");
//    }

    public static void pptx2Image(String pptFiles, String htmlDir, String imgDir) throws Exception {
        File pptFile = new File(pptFiles);
        FileInputStream is = new FileInputStream(pptFile);
        XMLSlideShow ppt = new XMLSlideShow(is);
        is.close();
        Dimension pgsize = ppt.getPageSize();
        StringBuilder content = new StringBuilder();
        content.append("<html>");
        content.append("<body>");
        XSLFSlide[] slides = ppt.getSlides();
        for (int i = 0; i < slides.length; i++) {
            String image = UUID.randomUUID() + ".png";
            String webImagePath = imgDir + image;
            POIUtils.createDir(imgDir);
            try {
                // 防止中文乱码
                for (XSLFShape xslfShape : slides[i].getShapes()) {
                    if (!(xslfShape instanceof XSLFTextShape)) {
                        continue;
                    }
                    XSLFTextShape xslfTextShape = (XSLFTextShape) xslfShape;
                    for (XSLFTextParagraph xslfTextParagraph : xslfTextShape) {
                        for (XSLFTextRun xslfTextRun : xslfTextParagraph) {
                            xslfTextRun.setFontFamily("宋体");
                        }
                    }
                }
                BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
                Graphics2D graphics = img.createGraphics();
                // clear the drawing area
//                graphics.setPaint(Color.white);
                graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
                // render
                slides[i].draw(graphics);
                // save the output
                FileOutputStream out = new FileOutputStream(imgDir + image);
                ImageIO.write(img, "png", out);
                out.close();
                content.append("<br />");
                content.append("<p style=text-align:center;>");
                content.append("<img src=" + "\"").append(webImagePath).append("\"").append("/>");
                content.append("</p>");
                content.append("<br />");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("第" + (i + 1) + "张ppt转换出错");
            }
        }

        content.append("</body>");
        content.append("</html>");
        String targetFileName = imgDir+htmlDir;
        FileUtils.writeStringToFile(new File(targetFileName), content.toString(), "utf-8");
    }
    
    public static void csdxToImage(String vsdxFiles, String htmlDir, String imgDir) {
    	String[] arguments = new String[] {"python", "visio2img.py",vsdxFiles,imgDir+"liuwenxu0821.jpg"};
        try {
            Process process = Runtime.getRuntime().exec(arguments);
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),"UTF-8"));
            String line = null;
	        while ((line = in.readLine()) != null) {  
	            System.out.println(line);  
	        }  
	        in.close();
	        //java代码中的process.waitFor()返回值为0表示我们调用python脚本成功，
            //返回值为1表示调用python脚本失败，这和我们通常意义上见到的0与1定义正好相反
	        int re = process.waitFor();  
	        System.out.println(re);
        } catch (Exception e) {
            e.printStackTrace();
        }  

    }
    
    public static void vsdxImage(String vsdxFiles, String htmlDir, String imgDir) throws Exception {
    	byte[] b1 =image2Bytes(vsdxFiles);
        String image = UUID.randomUUID() + ".png";
        String webImagePath = imgDir + image;
    	//存为文件
        buff2Image(b1,webImagePath);
        
        StringBuilder content = new StringBuilder();
        content.append("<html>");
        content.append("<body>");
            POIUtils.createDir(imgDir);
            try {
                content.append("<br />");
                content.append("<p style=text-align:center;>");
                content.append("<img src=" + "\"").append(webImagePath).append("\"").append("/>");
                content.append("</p>");
                content.append("<br />");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }

        content.append("</body>");
        content.append("</html>");
        String targetFileName = imgDir+htmlDir;
        FileUtils.writeStringToFile(new File(targetFileName), content.toString(), "utf-8");
    }
    
    //
    private static void buff2Image(byte[] b,String tagSrc) throws Exception{
        FileOutputStream fout = new FileOutputStream(tagSrc);
        //将字节写入文件
        fout.write(b);
        fout.close();
    }
    //文件转换为字节流
    private static byte[] image2Bytes(String imgSrc) throws Exception{
        FileInputStream fin = new FileInputStream(new File(imgSrc));
        //可能溢出,简单起见就不考虑太多,如果太大就要另外想办法，比如一次传入固定长度byte[]
        byte[] bytes  = new byte[fin.available()];
        //将文件内容写入字节数组，提供测试的case
        fin.read(bytes);
        
        fin.close();
        return bytes;
    }

	/**
	 * 将文件内容写入指定html文件
	 * @param content 内容
	 * @param outFilePath 输出文件路径 path+fileName
	 */
	private static void writeFile(String content, String outFilePath) {
		FileOutputStream fos = null;
		BufferedWriter bw = null;
		try {
			File file = new File(outFilePath);
			fos = new FileOutputStream(file);
			bw = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"));
			bw.write(content);
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			try {
				if (bw != null)
					bw.close();
				if (fos != null)
					fos.close();
			} catch (IOException ie) {
			}
		}
	}

	/*文件下载*/
	public static boolean downloadFile(String filePath, String fileName, String downloadName,String contentType, HttpServletResponse response){
		boolean flag=true;
		try {
			File file = new File(filePath + fileName);
			if (!file.exists()) {
				flag = false;
			} else {
				FileInputStream fileInputStream = new FileInputStream(file);
				response.setHeader("Content-Disposition",
						"attachment;Filename=" + URLEncoder.encode(downloadName, "UTF-8"));
				response.setHeader("Content-Type", contentType);//设置格式类型
				OutputStream outputStream = response.getOutputStream();
				byte[] bytes = new byte[2048];
				int len = 0;
				while ((len = fileInputStream.read(bytes)) > 0) {
					outputStream.write(bytes, 0, len);
				}
				fileInputStream.close();
				outputStream.close();
			}
		}catch (IOException e){
			e.printStackTrace();
			flag = false;
		}
		return flag;
	}
}

